package dictionary

import (
    "time"

    "github.com/gin-gonic/gin"
    "gorm.io/gorm"
    "iip/dictionary/model"
    "libgo/utils/copier"
)

func (s *Dictionary) ExternalProjectCreate(c *gin.Context) {
    req := &struct {
        Name         string `form:"name"          json:"name"          binding:"required"`
        Description  string `form:"description"   json:"description"   binding:""`
        ContactName  string `form:"contact_name"  json:"contact_name"  binding:""`
        ContactPhone string `form:"contact_phone" json:"contact_phone" binding:""`
        TimeBegin    string `form:"time_begin"    json:"time_begin"    binding:""`
        TimeEnd      string `form:"time_end"      json:"time_end"      binding:""`
        ReqLocation
    }{}
    if err := c.ShouldBind(req); err != nil {
        s.json_error(c, err.Error())
        return
    }
    time_begin, err := time.Parse("2006-01-02", req.TimeBegin)
    if err != nil {
        s.logger.Error(err.Error())
    }
    time_end, err := time.Parse("2006-01-02", req.TimeEnd)
    if err != nil {
        s.logger.Error(err.Error())
    }


    loc := model.DictLocation{}
    loc.ID = s.idgen.NextID()
    copier.GormCopy(&loc, req)


    row := model.DictExternalProject{}
    row.ID = s.idgen.NextID()
    copier.GormCopy(&row, req)
    row.TimeBegin = time_begin
    row.TimeEnd = time_end

    err = s.gorm().Transaction(func(tx *gorm.DB) error {

        if err := s.gorm().Create(&loc).Error; err != nil {
            return err
        }

        row.LocationID = loc.ID
        if err := s.gorm().Create(&row).Error; err != nil {
            s.json_error(c, err.Error())
            return err
        }
        return nil
    })
    if err != nil {
        s.json_error(c, err.Error())
        return
    }
    s.logger.Info("create external project done")
    s.json_data(c, s.external_project_full(&row, &loc))
}

func (s *Dictionary) ExternalProjectDelete(c *gin.Context) {
    req := &struct {
        ID int64 `uri:"id"`
    }{}
    if err := c.ShouldBindUri(req); err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }

    if err := s.gorm().Delete(&model.DictExternalProject{ID: req.ID}).Error; err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }
    s.logger.Info("delete external project by id ", req.ID)
    s.json_ok(c)
}

func (s *Dictionary) ExternalProjectPagedList(c *gin.Context) {

    query := &struct {
        Page     int    `form:"page" binding:"required,gte=1" json:"page"`
        PageSize int    `form:"pagesize" binding:"required,gte=1" json:"pagesize"`
        Order    string `form:"order" json:"order"`
    }{}
    if err := c.ShouldBindQuery(query); err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }
    if query.Order != "asc" && query.Order != "desc" {
        query.Order = "asc"
    }


    var total int64
    if err := s.gorm().Model(&model.DictExternalProject{}).Count(&total).Error; err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }

    var com_lst []*model.DictExternalProject
    if err := s.gorm().Limit(query.PageSize).Offset(query.PageSize * (query.Page - 1)).Order("id " + query.Order).Find(&com_lst).Error; err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }

    var lst []interface{}
    for _, com := range com_lst {
        loc, _ := s.GetLocationByID(com.LocationID)
        lst = append(lst, s.external_project_full(com, loc))
    }
    s.logger.Info("query external project paged list")
    s.json_paged_data(c, total, query.Page, query.PageSize, lst)
}

func (s *Dictionary) ExternalProjectByID(c *gin.Context) {
    req := &struct {
        ID int64 `uri:"id"`
    }{}
    if err := c.ShouldBindUri(req); err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }

    com, err := s.GetExternalProjectByID(req.ID)
    if err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }
    loc, err := s.GetLocationByID(com.LocationID)
    if err != nil {
        s.logger.Error(err)
        loc = &model.DictLocation{}
    }

    s.logger.Info("query external project by id ", req.ID)
    s.json_data(c, s.external_project_full(com, loc))
}

func (s *Dictionary) ExternalProjectUpdate(c *gin.Context) {

    req_id := &struct {
        ID int64 `uri:"id"`
    }{}
    if err := c.ShouldBindUri(req_id); err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }
    prj_old, err := s.GetExternalProjectByID(req_id.ID)
    if err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }
    loc_old, err := s.GetLocationByID(prj_old.LocationID)
    if err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }


    req := &struct {
        Name         string `form:"name"          json:"name"          binding:"required"`
        Description  string `form:"description"   json:"description"   binding:""`
        ContactName  string `form:"contact_name"  json:"contact_name"  binding:""`
        ContactPhone string `form:"contact_phone" json:"contact_phone" binding:""`
        TimeBegin    string `form:"time_begin"    json:"time_begin"    binding:""`
        TimeEnd      string `form:"time_end"      json:"time_end"      binding:""`
        ReqLocation
    }{}
    if err := c.ShouldBind(req); err != nil {
        s.json_error(c, err.Error())
        return
    }
    time_begin, err := time.Parse("2006-01-02", req.TimeBegin)
    if err != nil {
        s.logger.Error(err.Error())
    }
    time_end, err := time.Parse("2006-01-02", req.TimeEnd)
    if err != nil {
        s.logger.Error(err.Error())
    }

    copier.GormCopy(&prj_old, req)
    prj_old.TimeBegin = time_begin
    prj_old.TimeEnd = time_end

    copier.GormCopy(loc_old, req)

    err = s.gorm().Transaction(func(tx *gorm.DB) error {
        if err := s.db.Save(prj_old).Error; err != nil {
            return err
        }
        if err := s.db.Save(loc_old).Error; err != nil {
            return err
        }
        return nil
    })

    if err != nil {
        s.logger.Error(err.Error())
        s.json_error(c, err.Error())
        return
    }

    s.logger.Info("update external project id=", prj_old.ID)
    s.json_data(c, s.external_project_full(prj_old, loc_old))
}
